package zack.gateway.center.domain.manage.service;

import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import zack.gateway.center.application.IConfigManageService;
import zack.gateway.center.domain.manage.model.aggregates.ApplicationSystemRichInfo;
import zack.gateway.center.domain.manage.model.vo.ApplicationInterfaceMethodVO;
import zack.gateway.center.domain.manage.model.vo.GatewayServerDetailVO;
import zack.gateway.center.domain.manage.model.vo.GatewayServerVO;
import zack.gateway.center.domain.manage.repository.IConfigManageRepository;
import zack.gateway.center.domain.manage.model.vo.ApplicationInterfaceVO;
import zack.gateway.center.domain.manage.model.vo.ApplicationSystemVO;
import zack.gateway.center.domain.manage.repository.InterfaceKey;
import zack.gateway.center.infrastructure.common.Constants;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author   zack
 * @description 网关配置服务
   */
@Service
public class ConfigManageService implements IConfigManageService {

    @Resource
    private IConfigManageRepository configManageRepository;

    @Override
    public List<GatewayServerVO> queryGatewayServerList() {
        return configManageRepository.queryGatewayServerList();
    }

    @Override
    public boolean registerGatewayServerNode(String groupId, String gatewayId, String gatewayName, String gatewayAddress) {
        GatewayServerDetailVO gatewayServerDetailVO = configManageRepository.queryGatewayServerDetail(gatewayId, gatewayAddress);
        if (null == gatewayServerDetailVO) {
            try {
                return configManageRepository.registerGatewayServerNode(groupId, gatewayId, gatewayName, gatewayAddress, Constants.GatewayStatus.Available);
            } catch (DuplicateKeyException e) {
                return configManageRepository.updateGatewayStatus(gatewayId, gatewayAddress, Constants.GatewayStatus.Available);
            }
        } else {
            return configManageRepository.updateGatewayStatus(gatewayId, gatewayAddress, Constants.GatewayStatus.Available);
        }
    }


    @Override
    public ApplicationSystemRichInfo queryApplicationSystemRichInfo(String gatewayId,String systemIdOut) {

        // 1. 查询出网关ID对应的关联系统ID集合。也就是一个网关ID会被分配一些系统RPC服务注册进来，需要把这些服务查询出来。
        List<String> systemIdList = configManageRepository.queryGatewayDistributionSystemIdList(gatewayId);
        if(null == systemIdList || systemIdList.isEmpty()){
            return null;
        }
        if(!systemIdOut.equals("")){
            systemIdList.add(systemIdOut);
        }
        // 2. 查询系统ID对应的系统列表信息
        List<ApplicationSystemVO> applicationSystemVOList = configManageRepository.queryApplicationSystemList(systemIdList);
        if(null == applicationSystemVOList || applicationSystemVOList.isEmpty()){
            return null;
        }
        List<ApplicationInterfaceVO> applicationInterfaceVOS = configManageRepository.queryApplicationInterfaceList(systemIdList);

        //将systemId和接口对应
        Map<String, List<ApplicationInterfaceVO>> interfaceMap = applicationInterfaceVOS.stream()
                .collect(Collectors.groupingBy(ApplicationInterfaceVO::getSystemId));
        List<InterfaceKey> interfaceKeys = applicationInterfaceVOS.stream()
                .map(interf -> new InterfaceKey(interf.getSystemId(), interf.getInterfaceId()))
                .collect(Collectors.toList());
        List<ApplicationInterfaceMethodVO> applicationInterfaceMethodVOS = configManageRepository.queryApplicationInterfaceMethodListByKeys(interfaceKeys);
        //组装applicationSystemVO
        Map<String, List<ApplicationInterfaceMethodVO>> methodMap = applicationInterfaceMethodVOS.stream()
                .collect(Collectors.groupingBy(me -> me.getSystemId() + ":" + me.getInterfaceId()));
        for(ApplicationSystemVO applicationSystemVO : applicationSystemVOList) {
            String systemId = applicationSystemVO.getSystemId();
            List<ApplicationInterfaceVO> interfaceVOList = interfaceMap.getOrDefault(systemId, Collections.emptyList());
            applicationSystemVO.setInterfaceList(interfaceVOList);
            for(ApplicationInterfaceVO applicationInterfaceVO : interfaceVOList) {
                String interfaceId = applicationInterfaceVO.getInterfaceId();
                List<ApplicationInterfaceMethodVO> methodVOList = methodMap.getOrDefault(systemId +":" + interfaceId, Collections.emptyList());
                applicationInterfaceVO.setMethodList(methodVOList);
            }
        }
        return new ApplicationSystemRichInfo(gatewayId, applicationSystemVOList);

    }

    @Override
    public String queryGatewayDistributionGatewayBySystemId(String systemId) {
        return configManageRepository.queryGatewayDistributionBySystemId(systemId);
    }

    @Override
    public List<GatewayServerDetailVO> queryGatewayServerDetailList() {
        List<GatewayServerDetailVO> gatewayServerDetailVOList = configManageRepository.queryGatewayServerDetailList();
        if(null == gatewayServerDetailVOList || gatewayServerDetailVOList.isEmpty()){
            return Collections.emptyList();
        }
        return gatewayServerDetailVOList;
    }

    @Override
    public void distributionGatewayServerNode(String groupId, String gatewayId, String systemId) {
       ApplicationSystemVO systemVO = configManageRepository.queryApplicationSystemBySystemId(systemId);
        String systemName = systemVO.getSystemName();
        if(StringUtils.isBlank(systemName)){
            throw new RuntimeException("网关算力与系统挂载配置失败，systemId：" + systemId + " 在数据库表「application_system」中不存在！");
        }
        configManageRepository.distributionGatewayServerNode(groupId,gatewayId,systemId,systemName);
    }
}
